package emulator.hardware.nmos6502.commands;

import emulator.EmulatorException;
import emulator.hardware.HwByte;
import emulator.hardware.nmos6502.Command;
import emulator.hardware.nmos6502.CommandSet;
import emulator.hardware.nmos6502.Cpu6502;
import emulator.hardware.nmos6502.Flags6502;
import emulator.hardware.nmos6502.Operand;
import emulator.hardware.nmos6502.operands.Absolute;
import emulator.hardware.nmos6502.operands.AbsoluteX;
import emulator.hardware.nmos6502.operands.Accumulator;
import emulator.hardware.nmos6502.operands.ZeroPage;
import emulator.hardware.nmos6502.operands.ZeroPageX;

/** ASL (Arithmetic Shift Left)
 *  
 *  Affects Flags: S Z C
 *  
 *  MODE           SYNTAX       HEX LEN TIM
 *  Accumulator   ASL A         $0A  1   2
 *  Zero Page     ASL $44       $06  2   5
 *  Zero Page,X   ASL $44,X     $16  2   6
 *  Absolute      ASL $4400     $0E  3   6
 *  Absolute,X    ASL $4400,X   $1E  3   7
 *  
 *  ASL shifts all bits left one position. 0 is shifted into bit 0 and the
 *  original bit 7 is shifted into the Carry.
 */ 
public class ASL implements Command {

	@Override
	public void execute(Cpu6502 cpu, Operand operand) throws EmulatorException {
		int value = (int) operand.getByte().getNumber();
		Flags6502 flags = cpu.getFlags();
		value <<= 1;
		flags.setCarry(value > 255);
		value &= 0xff;
		flags.setNZFromValue(value);
		operand.setByte(new HwByte(value));
		cpu.setFlags(flags);
	}

	@Override
	public String getName() {
		return "ASL";
	}

	@Override
	public void register(CommandSet cset) {
		 cset.defineCommand(0x0A, this, new Accumulator());
		 cset.defineCommand(0x06, this, new ZeroPage(), 4);
		 cset.defineCommand(0x16, this, new ZeroPageX(), 4);
		 cset.defineCommand(0x0E, this, new Absolute(), 4);
		 cset.defineCommand(0x1E, this, new AbsoluteX(false), 5);
	}

}
